'''
Created on 18/05/2013

@author: belentwi
'''


from app import db
from flask import Blueprint
from flask import request
from flask import render_template
from flask import redirect
from flask import url_for
from flask import flash

from app.models.solicitud_cambio import SolicitudCambio
from app.models.fase import Fase
from app.models.item import Item
from app.models.voto import Voto
from app.wtforms.solicitud_cambio_forms import SolicitudBuscar
from app.wtforms.solicitud_cambio_forms import ConsultarSolicitud
from app.wtforms.solicitud_cambio_forms import CrearSolicitud
from app.wtforms.solicitud_cambio_forms import VotacionSolicitud
from app.security import permission
from app.security import g
from app.controllers.linea_base_controller import eliminar_lb
from app.models.linea_base import LineaBase
from app.models.solicitud_cambio_reporte import SolicitudCambioReporte

from app.controllers.calculo_impacto_controller import calculo_impacto_grup
from app.controllers.calculo_impacto_controller import calculo_costo

from app.reportes.solicitud_reporte import SolicitudReport
from geraldo.generators import PDFGenerator
import os
mod = Blueprint('solicitudes', __name__, url_prefix='/solicitud')


@mod.route('/administracion/', methods=['GET', 'POST'])
@permission('ADMINISTRACION_SOLICITUDES')
def administracion_solicitud():
       
    """
    Muestra en pantalla las solicitudes que existen en la base de datos.
    Si no recibe algun filtro como parametro, lista todas solicitudes.
    Si recibe algun filtro, muestra las solicitudes que cumplen con el filtro indicado
    """
    # Obtenemos el formulario
    form =  SolicitudBuscar(request.form)    
      
    # Obtenemos el filtro
    impactoFilter = form.impacto_total.data
    estadoFilter = form.estado.data
    observacionFilter = form.observacion.data
    
    if(impactoFilter == None):
        impactoFilter = '' 
    if(estadoFilter == None):
        estadoFilter = ''  
    if(observacionFilter == None):
        observacionFilter = ''  
  
    solicitudes = SolicitudCambio.query.filter(SolicitudCambio.creador_id == g.user.id, SolicitudCambio.estado.like('%'+estadoFilter+'%'), SolicitudCambio.impacto_total.like('%'+impactoFilter+'%'), SolicitudCambio.observacion.like('%'+observacionFilter+'%'))
    solicitudes = solicitudes.all()    
             
        
    return render_template('solicitud_cambio/administracion_solicitud.html', form = form, solicitudes = solicitudes)




@mod.route('/crear/', methods=['GET', 'POST'])
#@permission('CREAR_ATRIBUTO')
def crear_solicitud():
    """
    Muestra en pantalla el formulario de creacion de una solicitud de cambio, valida los datos ingresados por
    el usuario y se hayan ingresado los datos obligatorios. Luego almacena en base de datos
    """
    
    choicesItems = []
    idList = []
    proyecto = g.proyecto
    permisos = g.permisos
    
    fases = proyecto.fases
    for fase in fases:
        for permiso in permisos:
            if(permiso.nombre == 'MODIFICAR' and permiso.entidad_id == fase.entidad_id):
                idList.append(fase.id)
        
    items = Item.query.filter_by(estado = 'Bloqueado').join(Fase).filter(Fase.id.in_(idList) ).all()

    for item in items:
        if(len(item.solicitud) == 0):
            choicesItems.append((str(item.id), item.nombre))

    form = CrearSolicitud(request.form)
    
    form.items.choices = choicesItems
    
        
    items = []
    if form.validate_on_submit():
        for id_item in form.items.data:
            item = Item.query.filter_by(id = int(id_item)).first()
            items.append(item)
            
        costo_total = calculo_costo(items)
        impacto_total = calculo_impacto_grup(items)
        observacion = form.observacion.data
        estado = 'Activa'
            
        creador = g.user  
        proyecto = g.proyecto
        solicitud = SolicitudCambio(impacto_total, costo_total, estado, observacion, items, creador, proyecto)
        db.session.add(solicitud)
        db.session.commit()
        flash('La solicitud ha sido registrada con exito')     
        return redirect(url_for('solicitudes.administracion_solicitud'))
  
    return render_template("solicitud_cambio/crear_solicitud.html", form = form)


@mod.route('/consultar/<solicitud>/', methods=['GET', 'POST'])
#@permission('VER_ROL')
def consultar_solicitud(solicitud):
    """
    Muestra en pantalla el formulario de consulta de solicitudes, muestra todos los datos a la 
    solicitud relacionada
    @param solicitud: id de la solicitud que se desea consultar
    """
    # Obtenemos el formulario
    form = ConsultarSolicitud(request.form)
    
    solicitud = SolicitudCambio.query.filter_by(id = solicitud).first()
    
    itemChoices = []
    for item in solicitud.items:
        itemChoices.append( (str(item.id), 'Item: ' +item.nombre + '               Costo: ' + str(item.costo)) )
        
    form.costo_total.data = solicitud.costo_total
    form.impacto_total.data = solicitud.impacto_total
    form.creador.data = solicitud.creador.nombre
    form.observacion.data = solicitud.observacion
    form.estado.data = solicitud.estado
    form.items.choices = itemChoices
    
    if form.validate_on_submit():
        
        #Cuando el usuario presiona aceptar, redirigimos a la pagina de administracion de roles
        return redirect(url_for('solicitudes.administracion_solicitud'))
    
    return render_template('solicitud_cambio/consultar_solicitud.html', form = form)
    
    


@mod.route('/modificar/<solicitud>/', methods=['GET', 'POST'])
#@permission('MODIFICAR_ROL')

def modificar_solicitud(solicitud):
    """
    Muestra en pantalla el formulario de modificacion de una solicitud de cambio, valida los datos ingresados por
    el usuario y se hayan ingresado los datos obligatorios. Luego almacena en base de datos
    @param solicitud: id de la solicitud que se desea modificar
    """
    # Obtenemos el formulario
    form = CrearSolicitud(request.form)
    
    idList = []
    proyecto = g.proyecto
    
    fases = proyecto.fases
    for fase in fases:
        idList.append(fase.id)
    
    solicitud = SolicitudCambio.query.filter_by(id = solicitud).first()
    if(solicitud.estado == 'Activa'):
        
        choicesItems = []
        
        items = Item.query.filter_by(estado = 'Bloqueado').join(Fase).filter(Fase.id.in_(idList) ).all()
        
        for item in items:    
            choicesItems.append((str(item.id), item.nombre))
               
        form.items.choices = choicesItems
        if form.validate_on_submit():
            solicitud.observacion = form.observacion.data
            
            items = []
            for id_item in form.items.data:
                item = Item.query.filter_by(id = int(id_item)).first()
                items.append(item)
            
            solicitud.items = items
            solicitud.costo_total= calculo_costo(items)
            solicitud.impacto_total= calculo_impacto_grup(items)
            
            db.session.add(solicitud)
            db.session.commit()
                    
            # Retornamos a la pagina de administracion de roles
            flash('La solicitud ha sido actualizada con exito')
            return redirect(url_for('solicitudes.administracion_solicitud'))   
               
               
                
        form.observacion.data = solicitud.observacion   
        
        
        choicesData = []
        for item in solicitud.items:
            choicesData.append(str(item.id))
        form.items.data = choicesData
        
        
        return render_template('solicitud_cambio/modificar_solicitud.html', form = form)
    else:
        flash('La solicitud no puede ser modificada')
        return redirect(url_for('solicitudes.administracion_solicitud'))


@mod.route('/eliminar/<solicitud>/', methods=['GET', 'POST'])
#@permission('ELIMINAR_ATRIBUTO')
def eliminar_solicitud(solicitud):
    """
        Muestra en pantalla el formulario de eliminacion de solicitudes, se pide la confimacion del usuario 
        y se elimina la solicitud.
        
        @param solicitud: id de la solicitud que se desea eliminar.
    """

   
    solicitud_seleccionada = SolicitudCambio.query.filter_by(id=solicitud).first()
    
    db.session.delete(solicitud_seleccionada)
    db.session.commit()
    flash('Se ha eliminado la solicitud exitosamente')
 
            
    return redirect(url_for('solicitudes.administracion_solicitud'))

@mod.route('/enviar/<solicitud>/', methods=['GET', 'POST'])
def enviar_solicitud(solicitud):
    """
        Muestra en pantalla el formulario de envio de solicitudes.
        
        @param solicitud: id de la solicitud que se desea enviar.
    """
    solicitud_seleccionada = SolicitudCambio.query.filter_by(id=solicitud).first()
    if(solicitud_seleccionada.estado == 'Activa'):
        solicitud_seleccionada.estado = 'Votacion'
        db.session.add(solicitud_seleccionada)
        db.session.commit()
    else:
        flash('La solicitud no puede ser enviada')
    return redirect(url_for('solicitudes.administracion_solicitud'))




@mod.route('/ver_solicitudes/', methods=['GET', 'POST'])
def ver_solicitudes_comite():
       
    """
        Muestra en pantalla las solicitudes que existen en la base de datos que corresponden al comite del proyecto.
    """
    # Obtenemos el formulario
    
      
    proyecto_login = g.proyecto
    comite_miembros = proyecto_login.comite.miembros 
    usuario = g.user
    if(usuario in comite_miembros ):
        
        
        solicitudes = SolicitudCambio.query.filter_by(proyecto_id = proyecto_login.id)
        solicitudes = solicitudes.all()    
                 
            
        return render_template('solicitud_cambio/ver_solicitudes_comite.html', solicitudes = solicitudes)
    else:
        flash('Usted no pertenece al comite de cambio de este proyecto')
        return redirect(url_for('solicitudes.administracion_solicitud'))
    
    
@mod.route('/votar/<solicitud>/', methods=['GET', 'POST'])
def votar(solicitud):
    """
        Muestra en pantalla el formulario de votacion.
        @param solicitud: id de la solicitud que se desea votar.
    """
    usuario = g.user
    proyecto_login = g.proyecto
    
    solicitud_seleccionada = SolicitudCambio.query.filter_by(id=solicitud).first()
    
    
    opciones = ((str(1), 'Aprobar'), (str(2), 'No Aprobar'))
    if(solicitud_seleccionada.estado == 'Votacion'):
        voto_verificado = Voto.query.filter_by(id_solicitud = solicitud, id_usuario = usuario.id).first()
        
        if(voto_verificado == None):
            form = VotacionSolicitud(request.form)
            form.opciones.choices = opciones
            
            if form.validate_on_submit():
                if(form.opciones.data == '1'):
                    valor_voto = 1
                else:
                    valor_voto = 0
                voto = Voto(solicitud_seleccionada.id, usuario.id, valor_voto)
                
                db.session.add(voto)
                db.session.commit()
                cantidad_miembros = proyecto_login.comite.cantidad_miembros
                cantidad_votos = solicitud_seleccionada.cantidad_votos + 1
                solicitud_seleccionada.cantidad_votos = cantidad_votos
                db.session.add(solicitud_seleccionada)
                db.session.commit()
                if(solicitud_seleccionada.cantidad_votos == cantidad_miembros):
                    votos = Voto.query.filter_by(id_solicitud = solicitud_seleccionada.id )
                    resultado = 0
                    for votito in votos:
                        resultado = resultado + votito.voto 
                        
                    minimo = (cantidad_miembros/2)+1
                    
                    if(resultado >= minimo):
                        solicitud_seleccionada.estado = 'Aprobada'
                        items = solicitud_seleccionada.items
                        for item in items:
                            #===================================================
                            # id_lb = item.linea_base.id
                            # linea_base = LineaBase.query.filter_by(id= id_lb)
                            #===================================================
                            eliminar_lb(item.linea_base.id)
                            item.estado = 'Activo'
                            db.session.add(item)
                            
                        db.session.add(solicitud_seleccionada)
                        db.session.commit()
                        return redirect(url_for('solicitudes.administracion_solicitud'))
                    else:
                        solicitud_seleccionada.estado = 'Rechazada'   
                            
                        db.session.add(solicitud_seleccionada)
                        db.session.commit()
                        return redirect(url_for('solicitudes.administracion_solicitud'))
                           
                            
                else:                    
                    return redirect(url_for('solicitudes.administracion_solicitud'))
            return render_template("solicitud_cambio/votacion_solicitud.html", form =  form, opciones = opciones)
        else:
            flash('Usted ya ha votado')
            
            return redirect(url_for('solicitudes.administracion_solicitud'))

       
    else:
        flash('La solicitud no puede ser votada')
        return redirect(url_for('solicitudes.administracion_solicitud'))

@mod.route('/reporte_solicitud/', methods=['GET', 'POST'])
def reporte_solicitud():
       
    """
        Muestra en pantalla las solicitudes que existen en la base de datos que corresponden al comite del proyecto.
    """
    # Obtenemos el formulario
    
      
    proyecto_login = g.proyecto
    
        
    if(proyecto_login.lider_id == g.user.id):    
        solicitudes = SolicitudCambio.query.filter_by(proyecto_id = proyecto_login.id)
        solicitudes = solicitudes.all()  
        
        for solicitud in solicitudes:
            items = solicitud.items
            lista_nombres = []
            for item in items:
                
                if(item.linea_base.nombre not in lista_nombres):
                    lista_nombres.append(item.linea_base.nombre)
                
            
            lider_id = proyecto_login.lider_id
            voto_verificado = Voto.query.filter_by(id_solicitud = solicitud.id, id_usuario = lider_id).first()
            
            
                
            if(voto_verificado == None):
                voto = 'Votado'
            else:
                voto = 'No Votado'
               
            solicitudes_reporte = [] 
            for nombre in lista_nombres:
                solicitud_reporte = SolicitudCambioReporte()
                solicitud_reporte.setId(solicitud.id)
                solicitud_reporte.setObservacion(solicitud.observacion)
                solicitud_reporte.setLineBase(nombre)
                solicitud_reporte.setCreador(solicitud.creador.nombre)
                solicitud_reporte.setVoto(voto)
                solicitud_reporte.setEstado(solicitud.estado)
                
                
                solicitudes_reporte.append(solicitud_reporte)     
        
        report = SolicitudReport(solicitudes_reporte)
    
        cur_dir = os.path.dirname(os.path.abspath(__file__))
        reporte_dir = cur_dir + '/pdf'
        
        nombre = 'reporte_solicitud.pdf'
        #-------------------------------- if reporte_dir.isfile('reporte_item.pdf'):
            #----------------------------------------- nombre = 'reporte_item_2.pdf'
            
        report.generate_by(PDFGenerator, filename=os.path.join(reporte_dir , nombre))
        ruta = '/usr/bin/gnome-open ' + reporte_dir + '/' + nombre
        os.system(ruta) 
        return redirect(url_for('solicitudes.administracion_solicitud'))
                 
    else:
        flash('No tiene permisos para ver el reporte')        
        return redirect(url_for('solicitudes.administracion_solicitud'))
   


    
